package v1

import (
	"easyVolunteer/model"
	"easyVolunteer/utils/code"
	"easyVolunteer/utils/errno"
	"fmt"
	"github.com/gin-gonic/gin"
	"log"
	"net/http"
	"strconv"
	"strings"
)

// JoinIn 用户参加活动
func JoinIn(c *gin.Context) {
	activityID, _ := strconv.Atoi(c.Query("activityID"))
	userID := c.Query("userID")
	// 数据验证
	if model.Digits(uint64(activityID)) != code.ActivityIDDigitsNum || len(userID) != 10 {
		c.JSON(http.StatusOK, gin.H{
			"code": errno.ErrValidateFail.Code,
			"msg":  errno.ErrValidateFail.Message,
		})
		return
	}

	// 首先检查活动是否存在
	exist := model.CheckActivityExist(uint64(activityID))
	if !exist {
		c.JSON(http.StatusOK, gin.H{
			"code": errno.ErrActivityNotExist.Code,
			"msg":  errno.ErrActivityNotExist.Message,
		})
		return
	}

	// 判断该用户是否已经加入了活动

	ifJoin := model.GetUserIfJoinActivity(uint64(activityID), userID)
	if ifJoin {
		c.JSON(http.StatusOK, gin.H{
			"code": errno.ErrActivityHasJoinIn.Code,
			"msg":  errno.ErrActivityHasJoinIn.Message,
		})
		return
	}
	// 获得此活动的核心信息，招募人数，库存，招募范围
	a, err := model.FindActivityInfo(uint64(activityID), "limits", "stock", "range", "status")
	if err != errno.OK {
		fmt.Println(err)
		c.JSON(http.StatusOK, gin.H{
			"code": err.Code,
			"msg":  err.Message,
		})
		return
	}
	// 不处于招募状态
	if a.Status != code.ActivityRecruiting {
		c.JSON(http.StatusOK, gin.H{
			"code": errno.ErrActivityNotRecruit.Code,
			"msg":  errno.ErrActivityNotRecruit.Message,
		})
		return
	}
	// 已经招募完成
	if a.Stock <= 0 {
		c.JSON(http.StatusOK, gin.H{
			"code": errno.ErrActivityLimits.Code,
			"msg":  errno.ErrActivityLimits.Message,
		})
		return
	}

	// 活动有限制，先判断用户是否符合招募要求
	if a.Range != "-" {
		u, r := model.FindUserVolunteerInfo(userID)
		if r != errno.OK {
			c.JSON(http.StatusOK, gin.H{
				"code": r.Code,
				"msg":  r.Message,
			})
			return
		}
		if !strings.HasPrefix(u.GeneralInfoCode, a.Range) {
			c.JSON(http.StatusOK, gin.H{
				"code": errno.ErrUserNotInRecruirRang.Code,
				"msg":  errno.ErrUserNotInRecruirRang.Message,
			})
			return
		}
	}

	// 以下操作均在事务中进行
	// 用户加入活动，并且创建此活动和用户的关联
	status := model.JoinActivity(uint64(activityID), userID)

	c.JSON(http.StatusOK, gin.H{
		"code": status.Code,
		"msg":  status.Message,
	})
}

// QuitOut 用户退出活动
func QuitOut(c *gin.Context) {
	activityID, _ := strconv.Atoi(c.Query("activityID"))
	userID := c.Query("userID")

	// 数据验证
	if model.Digits(uint64(activityID)) != code.ActivityIDDigitsNum || len(userID) != 10 {
		c.JSON(http.StatusOK, gin.H{
			"code": errno.ErrValidateFail.Code,
			"msg":  errno.ErrValidateFail.Message,
		})
		return
	}

	// 直接查询活动信息，同时页获取活动信息
	activity, _ := model.FindActivityInfo(uint64(activityID), "status")
	if activity.Status == 0 {
		c.JSON(http.StatusOK, gin.H{
			"code": errno.ErrActivityNotExist.Code,
			"msg":  errno.ErrActivityNotExist.Message,
		})
		return
	}
	// 如果活动处于招募完成状态之后
	if activity.Status >= code.ActivityRecruited {
		c.JSON(http.StatusOK, gin.H{
			"code": errno.ErrActivityForbidQuit.Code,
			"msg":  errno.ErrActivityForbidQuit.Message,
		})
		return
	}
	status := model.QuitActivity(uint64(activityID), userID)

	c.JSON(http.StatusOK, gin.H{
		"code": status.Code,
		"msg":  status.Message,
	})
}

// SyncAllActivityHours 刷新所有活动时长记录到用户记录
func SyncAllActivityHours(c *gin.Context) {
	userID := c.Query("userID")

	status := model.SyncAllActivityHours(userID)
	c.JSON(http.StatusOK, gin.H{
		"code": status.Code,
		"msg":  status.Message,
	})
}

// GetUserHour 获得用户总时长
func GetUserHour(c *gin.Context) {
	userID := c.Query("userID")
	if len(userID) != 10 {
		log.Println("参数解析失败")
		c.JSON(http.StatusOK, gin.H{
			"code": errno.ErrParseParameter.Code,
			"msg":  errno.ErrParseParameter.Message,
		})
		return
	}
	hour, status := model.GetUserHour(userID)

	c.JSON(http.StatusOK, gin.H{
		"code": status.Code,
		"msg":  status.Message,
		"hour": hour,
	})
}

// GetUserAllActivity 获取用户参加的所有活动
func GetUserAllActivity(c *gin.Context) {
	userID := c.Query("userID")
	if len(userID) != 10 {
		log.Println("参数解析失败")
		c.JSON(http.StatusOK, gin.H{
			"code": errno.ErrParseParameter.Code,
			"msg":  errno.ErrParseParameter.Message,
		})
		return
	}
	activities, status := model.GetUserAllActivity(userID)

	c.JSON(http.StatusOK, gin.H{
		"code":       status.Code,
		"msg":        status.Message,
		"activities": activities,
	})
}

func GetUserInfo(c *gin.Context) {
	userID := c.Query("userID")
	if len(userID) != 10 {
		c.JSON(http.StatusOK, gin.H{
			"code": errno.ErrValidateFail.Code,
			"msg":  errno.ErrValidateFail.Message,
		})
		return
	}
	fmt.Println(userID)
	u, err := model.FindUserInfo(userID)
	if err != errno.OK {
		fmt.Println(err)
		c.JSON(http.StatusOK, gin.H{
			"code": errno.ErrFill.Code,
			"msg":  errno.Fail.Message,
		})
		return
	}

	instituteID, _ := strconv.Atoi(u.GeneralInfoCode[0:2])
	i := code.GetInstituteName(instituteID)
	majorID, _ := strconv.Atoi(u.GeneralInfoCode[2:4])
	m := code.GetMajorName(majorID)
	classNum := u.GeneralInfoCode[4:7]

	fmt.Println(i + m + classNum)
	c.JSON(http.StatusOK, gin.H{
		"code": errno.OK.Code,
		"msg":  errno.OK.Message,
		"name": u.Name,
		"info": i + "," + m + "," + classNum,
	})
}
